package com.andnnl.design.statemachine;

import org.squirrelframework.foundation.fsm.StateMachineBuilderFactory;
import org.squirrelframework.foundation.fsm.UntypedStateMachine;
import org.squirrelframework.foundation.fsm.UntypedStateMachineBuilder;
import org.squirrelframework.foundation.fsm.annotation.StateMachineParameters;
import org.squirrelframework.foundation.fsm.impl.AbstractUntypedStateMachine;

/**
 * https://codechina.csdn.net/mirrors/hekailiang/squirrel?utm_source=csdn_github_accelerator
 *
 * Created by chenss on 2021/5/21.
 */
public class QuickStartSample {

    // 1. Define State Machine Event
    enum FSMEvent {
        ToA, ToB, ToC, ToD
    }

    // 2. Define State Machine Class
    @StateMachineParameters(stateType=String.class, eventType=FSMEvent.class, contextType=Integer.class)
    static class StateMachineSample extends AbstractUntypedStateMachine {
        protected void fromAToB(String from, String to, FSMEvent event, Integer context) {
            System.out.println("Transition from '"+from+"' to '"+to+"' on event '"+event+
                    "' with context '"+context+"'.");
        }
        protected void fromBToC(String from, String to, FSMEvent event, Integer context) {
            System.out.println("Transition from '"+from+"' to '"+to+"' on event '"+event+
                    "' with context '"+context+"'.");
        }
        protected void fromCToD(String from, String to, FSMEvent event, Integer context) {
            System.out.println("Transition from '"+from+"' to '"+to+"' on event '"+event+
                    "' with context '"+context+"'.");
        }

        protected void anyToA(String from, String to, FSMEvent event, Integer context) {
            System.out.println("Transition from '"+from+"' to '"+to+"' on event '"+event+
                    "' with context '"+context+"'.");
        }

        protected void ontoB(String from, String to, FSMEvent event, Integer context) {
            System.out.println("Entry State \'"+to+"\'.");
        }
    }

    public static void main(String[] args) {
        // 3. Build State Transitions
        UntypedStateMachineBuilder builder = StateMachineBuilderFactory.create(StateMachineSample.class);
        builder.externalTransition().from("A").to("B").on(FSMEvent.ToB).callMethod("fromAToB");
        builder.externalTransition().from("B").to("C").on(FSMEvent.ToC).callMethod("fromBToC");
        builder.externalTransition().from("C").to("D").on(FSMEvent.ToD).callMethod("fromCToD");
        builder.transit().fromAny().to("D").onAny().callMethod("anyToA");
        builder.onEntry("B").callMethod("ontoB");

        // 4. Use State Machine
        UntypedStateMachine fsm = builder.newStateMachine("A");
        fsm.fire(FSMEvent.ToB, 10);
        fsm.fire(FSMEvent.ToC, 11);
        fsm.fire(FSMEvent.ToD, 12);
        fsm.fire(FSMEvent.ToA, 13);

        System.out.println("-----------------------------------------");
        // 4. Use State Machine
        UntypedStateMachine fsm2 = builder.newStateMachine("A");
        fsm2.fire(FSMEvent.ToB, 20);
        fsm2.fire(FSMEvent.ToC, 21);
//        fsm2.fire(FSMEvent.ToD, 22);
        System.out.println("-----------------------------------------");
        System.out.println("Current state is "+fsm.getCurrentState());
        System.out.println("Current state is "+fsm2.getCurrentState());
    }
}
